﻿using System;
using System.Collections;
using System.Globalization;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

using Microsoft.SharePoint;

namespace Mystery.SharePoint.WebControls
{
	[ToolboxData("<{0}:WebTemplatePicker runat=server></{0}:WebTemplatePicker>")]
	public class WebTemplatePicker : WebControl
	{
        private SPWebTemplate[] _availableTemplates = null;
        private string[] _availableCategories = null;
        private string _selectedTemplate;
        private string _selectedCategory;
        private DropDownList _languagePicker;

        public uint Lcid 
        { 
            get 
            {
                this.EnsureChildControls();

                if ((_languagePicker != null) &&
                    (_languagePicker.Items.Count > 0) &&
                    (String.IsNullOrEmpty(_languagePicker.SelectedValue) == false))
                {
                    return Convert.ToUInt32(_languagePicker.SelectedValue);
                }
                return SPContext.Current.Web.Language; 
            } 
        }

        public string SelectedTemplate
        {
            get
            {
                if (string.IsNullOrEmpty(_selectedTemplate) == true)
                {
                    _selectedTemplate = base.Page.Request.Form["SelectedTemplate"];
                }
                return _selectedTemplate;
            }
            set { _selectedTemplate = value; }
        }
        public string SelectedCategory
        {
            get
            {
                if (string.IsNullOrEmpty(_selectedCategory) == true)
                {
                    _selectedCategory = base.Page.Request.Form["SelectedCategory"];
                }

                // if nothing has been set, default category to first one in the list
                if (string.IsNullOrEmpty(_selectedCategory) == true)
                {
                    LoadAvailableTemplates();
                    if (_availableCategories.Length > 0)
                    {
                        _selectedCategory = _availableCategories[0];
                    }
                }
                return _selectedCategory;
            }
            set { _selectedCategory = value; }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            this.Controls.Add(CreateLanguagePicker());
            LoadAvailableTemplates();
            this.Controls.Add(CreateTabsRow());
            this.Controls.Add(CreatePickerLists());
            this.Controls.Add(CreateDescriptionText());

            RegisterClientScripts();
        }

        private Control CreateLanguagePicker()
        {
            SPWeb web = SPContext.Current.Web;
            Table tb = new Table();
            TableRow tr = new TableRow();
            tb.Rows.Add(tr);

            TableCell tcLabel = new TableCell();
            TableCell tcPicker = new TableCell();
            tr.Cells.Add(tcLabel);
            tr.Cells.Add(tcPicker);
            tcLabel.Controls.Add( new Label() { Text = Resources.LanguagePicker_Label });

            _languagePicker = new DropDownList();
            _languagePicker.AutoPostBack = true;
            tcPicker.Controls.Add(_languagePicker);
            
           
            SPLanguageCollection installedLanguages = web.RegionalSettings.InstalledLanguages;
            if (installedLanguages != null)
            {
                SortedList list = new SortedList();
                for (int i = 0; i < installedLanguages.Count; i++)
                {
                    int lCID = installedLanguages[i].LCID;
                    string displayName = installedLanguages[i].DisplayName;
                    ListItem item = new ListItem(displayName, lCID.ToString(CultureInfo.InvariantCulture));
                    list.Add(displayName, item);
                }
                for (int j = 0; j < list.Count; j++)
                {
                    _languagePicker.Items.Add((ListItem)list.GetByIndex(j));
                }
            }
            if (this.Page.IsPostBack == false)
            {
                _languagePicker.ClearSelection();
                string v = web.Language.ToString();
                foreach (ListItem item in _languagePicker.Items)
                {
                    item.Selected = (item.Value == v);
                }
            }
            return tb;
        }

        private LiteralControl CreateTabsRow()
        {
            StringBuilder sb = new StringBuilder();

            List<string> usedCategories = new List<string>();

            sb.Append("<div class=\"ms-templatepicker\">");

            for (int i = 0; i < _availableCategories.Length; i++)
            {
                string category = _availableCategories[i];

                string cssClass = "ms-templatepickerunselected";
                if (category == this.SelectedCategory)
                {
                    cssClass = "ms-templatepickerselected";
                }

                sb.AppendFormat("<div class=\"{0}\" id=\"Category_{1}\"><div><a href=\"javascript:ShowWebTemplates('{1}','{2}')\">{2}</a></div></div>",
                    cssClass, i, category);
            }
            sb.Append("</div>");

            return new LiteralControl(sb.ToString());
        }
        private LiteralControl CreatePickerLists()
        {
            StringBuilder sb = new StringBuilder();

            for (int c = 0; c < _availableCategories.Length; c++)
            {
                string category = _availableCategories[c];
                sb.AppendFormat("<select id=\"Templates_{0}\" style=\"display:none\" class=\"ms-templatepicker\" onchange=\"OnWebTemplateChange(this)\" size=\"12\">", c);

                for (int t = 0; t < _availableTemplates.Length; t++)
                {
                    SPWebTemplate template = _availableTemplates[t];
                    if (template.DisplayCategory == category)
                    {
                        sb.AppendFormat("<option value=\"{0}\">{1}</option>", template.Name, template.Title);
                    }
                }

                sb.Append("</select>");
            }

            return new LiteralControl(sb.ToString());
        }

        private LiteralControl CreateDescriptionText()
        {
            return new LiteralControl("<div style=\"width: 375px\" class=\"ms-descriptiontext\"><span id=\"WebTemplateDescription\"></span></div>");
        }
        
        private void LoadAvailableTemplates()
        {
            if ((_availableTemplates != null) &&
                (_availableCategories != null))
            {
                return;
            }
            // get a list of all the templates that we can use; automatically filters out other languages
            SPWebTemplateCollection allTemplates = SPContext.Current.Site.GetWebTemplates(this.Lcid);

            string[] available = SPContext.Current.Site.WebApplication.GetSiteProvisioningSettings().WebTemplates;
            //string[] available = new string[] { "STS#1" };

            List<SPWebTemplate> availableTemplates = new List<SPWebTemplate>();
            List<string> availableCategories = new List<string>();

            foreach (SPWebTemplate template in allTemplates)
            {
                if ((available.Contains(template.Name, StringComparer.InvariantCultureIgnoreCase) != false) &&
                    (template.IsSubWebOnly == false))
                {
                    if (availableCategories.Contains(template.DisplayCategory) == false)
                    {
                        availableCategories.Add(template.DisplayCategory);
                    }
                    availableTemplates.Add(template);
                }
            }
            _availableCategories = availableCategories.ToArray();
            _availableTemplates = availableTemplates.OrderBy(w => w.Title).ToArray();
        }

        protected void RegisterClientScripts()
        {
            var sb = new StringBuilder();

            // shows templates based on the selected category
            sb.AppendLine("function ShowWebTemplates(categoryId, categoryName)");
            sb.AppendLine("{");

            // first we hide or show the correct tabs
            sb.AppendFormat("		for(i=0; i < {0}; i++)", _availableCategories.Length);
            sb.AppendLine("			{");
            sb.AppendLine("				var o = document.getElementById('Templates_' + i);");
            sb.AppendLine("				var c = document.getElementById('Category_' + i);");
            sb.AppendLine();
            sb.AppendLine("				o.style.display = (i == categoryId) ? 'block' : 'none';");
            sb.AppendLine("				c.className = (i == categoryId) ? 'ms-templatepickerselected' : 'ms-templatepickerunselected';");
            sb.AppendLine("			}");

            // then we set the default select on the new show list
            sb.AppendLine("			var s = document.getElementById('Templates_' + categoryId);");
            sb.AppendLine("			s.options[0].selected = true;");
            // set the selection in the hidden fields
            sb.AppendLine("			var sc = document.getElementById('SelectedCategory');");
            sb.AppendLine("			sc.value = categoryName;");

            sb.AppendLine("			OnWebTemplateChange(s);");
            sb.AppendLine("}");

            // updates values as the selected teplate changes
            sb.AppendLine("function OnWebTemplateChange(obj)");
            sb.AppendLine("{");
            sb.AppendLine("		var d = document.getElementById('WebTemplateDescription');");
            sb.AppendLine("		var st = document.getElementById('SelectedTemplate');");

            sb.AppendLine("		d.innerHTML = descriptions[obj.value];");
            sb.AppendLine("		st.value = obj.value;");
            sb.AppendLine("}");

            sb.AppendLine("function SetInitialSelection(categoryId,categoryName,templateId)");
            sb.AppendLine("{");
            sb.AppendLine("		ShowWebTemplates(categoryId, categoryName);");
            sb.AppendLine("		if(templateId != '')");
            sb.AppendLine("		{");
            sb.AppendLine("		var s = document.getElementById('Templates_' + categoryId);");
            sb.AppendLine("		s.value = templateId;");
            sb.AppendLine("		}");
            sb.AppendLine("}");

            // create a dictionary of all the descriptions
            sb.AppendLine("var descriptions = [];");

            foreach (SPWebTemplate template in _availableTemplates)
            {
                sb.AppendFormat("descriptions['{0}'] = '{1}';", template.Name, template.Description);
            }

            Page.ClientScript.RegisterClientScriptBlock(GetType(), "WebTemplatePicker", sb.ToString(), true);
            Page.ClientScript.RegisterHiddenField("SelectedCategory", this.SelectedCategory);
            Page.ClientScript.RegisterHiddenField("SelectedTemplate", this.SelectedTemplate);

            // add a startup script to set the initial values
            if (string.IsNullOrEmpty(this.SelectedCategory) == false)
            {
                int id = 0;
                for (int i = 0; i < _availableCategories.Length; i++)
                {
                    if (_availableCategories[i] == this.SelectedCategory)
                    {
                        id = i;
                        break;
                    }
                }
                Page.ClientScript.RegisterStartupScript(this.GetType(), "WebTemplatePickerStartup",
                    string.Format(null, "SetInitialSelection('{0}','{1}','{2}');", id, this.SelectedCategory, this.SelectedTemplate), true);
            }
        }
	}
}
